home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume13 / make1.6 / part01 next >
Encoding:
Text File  |  1990-06-02  |  51.2 KB  |  1,702 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v13i018: PD make V1.6 (Part 1 of 2)
  3. From: greggy@zebra.UUCP (Greg Yachuk)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 18
  7. Submitted-by: greggy@zebra.UUCP (Greg Yachuk)
  8. Archive-name: make1.6/part01
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # If this archive is complete, you will see the following message at the end:
  17. #        "End of archive 1 (of 2)."
  18. # Contents:  README MANIFEST decl.h make.c make.doc
  19. # Wrapped by greggy@etude on Thu May 31 10:55:30 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'README' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'README'\"
  23. else
  24. echo shar: Extracting \"'README'\" \(5819 characters\)
  25. sed "s/^X//" >'README' <<'END_OF_FILE'
  26. XMake Version 1.6                    90-02-08
  27. X
  28. XThis is the source for a public domain version of make.  It is very
  29. Xsimilar to the `make' provided on Sun systems.  It is compiled with
  30. XMicrosoft C (5.1) and runs on PCDOS 3.3.  It also compiles and runs on
  31. XBSD 4.2 Unix.
  32. X
  33. XMany thanks to Dr. T. Andrews (uunet!cdin-1!cdis-1!tanner)
  34. X           Arend van den Brug (arend@philmds@philnl@mcvax)
  35. X           Jeff Fried (jfried@informix.com)
  36. X           Brian Wilson (island!sun!grenada!dr_unix)
  37. X           Kirk Bailey (bailey@mist.cs.orst)
  38. X
  39. Xfor pointing out problems and improvements.
  40. X
  41. XI have included a makefile and a (rudimentary) default.mk for BSD Unix.
  42. XUpdates, additions and corrections are welcomed.  The shar distribution
  43. Xhas the filenames reversed from the ZOO distribution:
  44. X
  45. X    ZOO distribution        shar distribution
  46. X    ----------------------------    --------------------------
  47. X    makefile    makefile.bsd    makefile.dos    makefile
  48. X    default.mk    default.bsd    default.dos    default.mk
  49. X
  50. X
  51. XI'm assuming that the ZOO is used on DOS and the shar on Unix.  If what
  52. Xyou got is not appropriate, rename the appropriate files and make.  For
  53. Xexample, if you got the DOS version on a Unix system:
  54. X
  55. X    mv makefile makefile.dos
  56. X    mv makefile.bsd makefile
  57. X    mv default.mk default.dos
  58. X    mv default.bsd default.mk
  59. X    make
  60. X
  61. XAlternatively, you can (probably) just use this following command:
  62. X
  63. X    make -r -f default.bsd -f makefile.bsd
  64. X===========================================================================
  65. XThis is version 1.6.  Here are the changes from 1.5 to 1.6:
  66. X
  67. X     accept and ignore the -b option for backwards compatibility.
  68. X
  69. X     accept and ignore the -- option for compatibility with SCO Xenix.
  70. X
  71. X     set up spawnvp() so that the wait() call works on non-BSD Unix.
  72. X
  73. X     translate "$$" to "$" when doing macro expansion.
  74. X
  75. X     set "$?" to the set of dependents younger than the current target.
  76. X
  77. X     support GnuMake's -W (What If) switch.
  78. X
  79. X     strip quotes from around arguments before spawning a command (DOS).
  80. X
  81. X     emulate inline-stdin redirection ("<<") on DOS by collecting the
  82. X     following commands into a temporary file and placing the filename
  83. X     on the command line.
  84. X
  85. X===========================================================================
  86. XThere is a version 1.4 that was submitted to comp.binaries.ibm.pc by
  87. XArend van den Brug.  I have incorporated many of the changes into my
  88. Xversion and called it 1.5.  These are the changes from 1.3 to 1.5:
  89. X
  90. X     support the -k, -S and -q options (see make.man).
  91. X
  92. X     correctly support the $(MAKE) macro.
  93. X
  94. X     allow target lines to end with a semi-colon and a command.
  95. X
  96. X     corrected bugs when allocated strings are over-run.
  97. X
  98. X     added "*?[]()&" to the list of characters that force the use of the
  99. X     shell on Unix.
  100. X
  101. X===========================================================================
  102. XThese are the changes from 1.2 to 1.3:
  103. X
  104. X     don't append shell command lines when encountering multiple targets
  105. X     of the same name.  if this is a *special* target (e.g.  .c.obj),
  106. X     just override.  otherwise exit with an error.
  107. X
  108. X     flush output before executing the command, so the output comes out
  109. X     in the right order when redirecting stdout to a file.
  110. X
  111. X     if a file is supposedly built, but does not exists, use current
  112. X     time.
  113. X
  114. X     exit with an error if a target line does not have a ':'.
  115. X
  116. X     don't force a space after "include" in case TAB is used.
  117. X
  118. X     D and F modifiers for Directory and Filename of $@, $<, $*.
  119. X
  120. X     use a dependent file for an implicit rule, if possible.
  121. X
  122. X     allow Makefile as well as makefile, for Unix.
  123. X
  124. X     always print statements when using -n, even if they start with @.
  125. X
  126. X     backquote (`) will force use of a shell, in Unix.
  127. X
  128. X===========================================================================
  129. XThese are the changes from 1.1 to 1.2:
  130. X
  131. X     ensure command line macros override makefile macros, even as
  132. X     makefiles are being read in.
  133. X
  134. X     support time checks correctly on MSDOS directories.
  135. X
  136. X     use MAKEFLAGS macro, and set it up for subordinate makes.
  137. X
  138. X     import environment variables and support -e flag.
  139. X
  140. X     handle `-f -' (i.e.  makefile from stdin) correctly.
  141. X
  142. X     clean up some potential NULL pointer dereferences.
  143. X
  144. X     correct errors in handling nested makes.
  145. X
  146. X     modify tokenizing routine to correctly handle trailing separators.
  147. X
  148. X     the documentation has been re-written
  149. X
  150. X===========================================================================
  151. XThese are the changes from 1.0 to 1.1:
  152. X
  153. X     modify prerequisite list handling to correctly allow a target to
  154. X     appear on multiple target lines.
  155. X
  156. X
  157. XThere is a short story which goes with this offering.  Sometime early in
  158. X1988, someone (possibly Dan Grayson) posted copyrighted source for a
  159. X`make' to Usenet.  I used it and modified it somewhat, and then lost my
  160. Xhard disk.  Having found this program to be very useful, I set about
  161. Xrewriting it from my recollection of the source that I had seen.  I have
  162. Xasked Rahul (moderator of comp.binaries.ibm.pc) if he could trace the
  163. Xoriginal submitter, and have also posted a note to the net in c.b.i.p.d,
  164. Xtrying to locate this person.  So far, no trace has been found.  I
  165. Xreally would like to show this source to him (and hopefully have him
  166. Xagree that it is not the same as his).
  167. X
  168. XI have based my algorithms on this previous source code.  Algorithms are
  169. Xnot copyrightable, so I feel that I have not infringed upon anyone's
  170. Xrights.  Also, I have acted in good faith trying to trace this person.
  171. XI hope that recipients of this code feel the same.  I am releasing this
  172. Xinto the public domain.  You may do anything you wish with it, even
  173. Xcopyright it yourself and try to sell it as your own.  Good luck, and
  174. Xhave fun.
  175. X
  176. X    -greg
  177. X
  178. XGreg Yachuk          Informix Software Inc., Menlo Park, CA 92025
  179. Xgreggy@informix.com | {uunet,pyramid}!infmx!greggy    (415) 926-6300
  180. END_OF_FILE
  181. if test 5819 -ne `wc -c <'README'`; then
  182.     echo shar: \"'README'\" unpacked with wrong size!
  183. fi
  184. # end of 'README'
  185. fi
  186. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  187.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  188. else
  189. echo shar: Extracting \"'MANIFEST'\" \(547 characters\)
  190. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  191. X   File Name        Archive #    Description
  192. X----------------------------------------------------------
  193. X README                     1    
  194. X MANIFEST                   1    This shipping list
  195. X build.c                    2    
  196. X decl.h                     1    
  197. X default.mk                 2    
  198. X default.msc                2    
  199. X make.c                     1    
  200. X make.doc                   1    
  201. X make.h                     2    
  202. X makefile                   2    
  203. X makefile.msc               2    
  204. X parse.c                    2    
  205. X tstring.c                  2    
  206. X tstring.h                  2    
  207. END_OF_FILE
  208. if test 547 -ne `wc -c <'MANIFEST'`; then
  209.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  210. fi
  211. # end of 'MANIFEST'
  212. fi
  213. if test -f 'decl.h' -a "${1}" != "-c" ; then 
  214.   echo shar: Will not clobber existing file \"'decl.h'\"
  215. else
  216. echo shar: Extracting \"'decl.h'\" \(2877 characters\)
  217. sed "s/^X//" >'decl.h' <<'END_OF_FILE'
  218. X/*
  219. X * decl.h
  220. X *
  221. X * 88-10-01 v1.0    created by greg yachuk, placed in the public domain
  222. X * 88-10-06 v1.1    changed prerequisite list handling
  223. X * 88-11-11 v1.2    fixed some bugs and added environment variables
  224. X * 89-07-12 v1.3    stop appending shell commands, and flush output
  225. X * 89-08-01 v1.4 AB    lots of new options and code
  226. X * 89-10-30 v1.5    -f -S -q options, took some changes from v1.4
  227. X * 90-04-18 v1.6    -b -- -W options, emulate <<, non-BSD cleanup
  228. X */
  229. X
  230. X#ifdef    __STDC__
  231. Xextern int main(int argc, char **argv);
  232. Xextern int make_args(int argc, char **argv);
  233. Xextern char **grow_list(char **list, int *len);
  234. Xextern FILE *fopenp(char *fname, char *type);
  235. Xextern int make(char *targname, int worry);
  236. Xextern int default_rule(char *targname, struct targnode * targetp, int worry, int mustbuild);
  237. Xextern char *get_preqname(struct targnode * targp, char *suffix, char *basename);
  238. Xextern int add_metas(char *basename, char *preqname, char *targname);
  239. Xextern int split_meta(char *sym, char *name);
  240. Xextern int touch_file(char *targname);
  241. Xextern int display_prereq(char *targname, long targtime, char *preqname, long preqtime);
  242. Xextern long file_time(char *fname, int built);
  243. Xextern int usage(void);
  244. Xextern int build(struct shellnode * *shellp);
  245. Xextern char *shellinput(struct shellnode * **shellp, char *eof);
  246. Xextern int new_make(char **argv);
  247. Xextern int parse(FILE * fd);
  248. Xextern int link_targs(struct targnode * *targs, struct filenode * *preqs, struct shellnode * *shells);
  249. Xextern int add_macro(char *input, int scmd);
  250. Xextern int add_symbol(char *name, char *value, int scmd);
  251. Xextern struct symnode *get_symbol(char *name, int scmd);
  252. Xextern struct symnode *dup_symbol(struct symnode * sp, char *svalue);
  253. Xextern struct targnode *add_target(char *name);
  254. Xextern struct targnode *hash_target(char *name, unsigned short *maskp);
  255. Xextern struct filenode *add_file(char *name);
  256. Xextern struct filenode *hash_file(char *name, unsigned short *maskp);
  257. Xextern char **append_node(char **node, char **adds, int size);
  258. Xextern struct shellnode *add_shell(char *input);
  259. Xextern char *breakout(char *input);
  260. X#else
  261. Xextern int main();
  262. Xextern int make_args();
  263. Xextern char **grow_list();
  264. Xextern FILE *fopenp();
  265. Xextern int make();
  266. Xextern int default_rule();
  267. Xextern char *get_preqname();
  268. Xextern int add_metas();
  269. Xextern int split_meta();
  270. Xextern int touch_file();
  271. Xextern int display_prereq();
  272. Xextern long file_time();
  273. Xextern int usage();
  274. Xextern int build();
  275. Xextern char *shellinput();
  276. Xextern int new_make();
  277. Xextern int parse();
  278. Xextern int link_targs();
  279. Xextern int add_macro();
  280. Xextern int add_symbol();
  281. Xextern struct symnode *get_symbol();
  282. Xextern struct symnode *dup_symbol();
  283. Xextern struct targnode *add_target();
  284. Xextern struct targnode *hash_target();
  285. Xextern struct filenode *add_file();
  286. Xextern struct filenode *hash_file();
  287. Xextern char **append_node();
  288. Xextern struct shellnode *add_shell();
  289. Xextern char *breakout();
  290. X#endif
  291. END_OF_FILE
  292. if test 2877 -ne `wc -c <'decl.h'`; then
  293.     echo shar: \"'decl.h'\" unpacked with wrong size!
  294. fi
  295. # end of 'decl.h'
  296. fi
  297. if test -f 'make.c' -a "${1}" != "-c" ; then 
  298.   echo shar: Will not clobber existing file \"'make.c'\"
  299. else
  300. echo shar: Extracting \"'make.c'\" \(18624 characters\)
  301. sed "s/^X//" >'make.c' <<'END_OF_FILE'
  302. X/*
  303. X * make.c    An imitation of the Unix MAKE facility
  304. X *
  305. X * 88-10-01 v1.0    created by greg yachuk, placed in the public domain
  306. X * 88-10-06 v1.1    changed prerequisite list handling
  307. X * 88-11-11 v1.2    fixed some bugs and added environment variables
  308. X * 89-07-12 v1.3    stop appending shell commands, and flush output
  309. X * 89-08-01 v1.4 AB    lots of new options and code
  310. X * 89-10-30 v1.5    -f -S -q options, took some changes from v1.4
  311. X * 90-04-18 v1.6    -b -- -W options, emulate <<, non-BSD cleanup
  312. X */
  313. X
  314. X#include <stdio.h>
  315. X#include <errno.h>
  316. X#include <fcntl.h>
  317. X#include <string.h>
  318. X#include <sys/types.h>
  319. X#include <sys/stat.h>
  320. X#include <time.h>
  321. X#ifdef    MSDOS
  322. X#include <stdlib.h>
  323. X#endif
  324. X
  325. X#include "make.h"
  326. X#include "tstring.h"
  327. X#include "decl.h"
  328. X
  329. X
  330. Xtargptr target_list = NULL;    /* list of target nodes */
  331. Xfileptr file_list = NULL;    /* list of file nodes */
  332. Xsymptr  symbol_list = NULL;    /* list of symbol nodes */
  333. Xshellptr shell_list = NULL;    /* list of shell nodes */
  334. X
  335. Xchar  **shell_cmds = NULL;    /* commands which force a SHELL */
  336. X
  337. Xint     make_level = 0;        /* for counting new_make()'s */
  338. X
  339. Xtargptr first_targ = NULL;    /* first target, in case nothing explicit */
  340. Xtargptr suffix_targ = NULL;    /* .SUFFIXES target pointer */
  341. X
  342. Xchar  **tlist = NULL;        /* command line targets */
  343. Xchar  **flist = NULL;        /* command line make files */
  344. Xchar  **mlist = NULL;        /* command line macros */
  345. X
  346. Xint     tmax = 0;        /* max size of tlist */
  347. Xint     fmax = 0;        /* max size of flist */
  348. Xint     mmax = 0;        /* max size of mlist */
  349. X
  350. Xoptnode opts;            /* all the options */
  351. Xint     readdef = 1;        /* -r option */
  352. Xint     dispcount = 0;        /* used for -D option */
  353. X
  354. Xlong    now;            /* time at startup */
  355. Xchar   *makeflags;        /* value to update the MAKEFLAGS macro with */
  356. X
  357. X
  358. Xmain(argc, argv)
  359. Xint     argc;
  360. Xchar  **argv;
  361. X{
  362. X    int     i;
  363. X    targptr targp;
  364. X    int     mk;
  365. X    symptr  symp;
  366. X    char   *envp;
  367. X    char  **envv;
  368. X
  369. X    /* initialize the various global lists */
  370. X
  371. X    opts.depend = 0;
  372. X    dispcount = 0;
  373. X
  374. X    target_list = NULL;
  375. X    file_list = NULL;
  376. X    shell_list = NULL;
  377. X    /* don't set symbol_list to NULL, or recursive makes won't work */
  378. X
  379. X    /* allocate space for command line targets, files and macros */
  380. X
  381. X    tlist = grow_list(NULL, &tmax);
  382. X    flist = grow_list(NULL, &fmax);
  383. X    mlist = grow_list(NULL, &mmax);
  384. X
  385. X    /* process MAKEFLAGS environment variable, first */
  386. X
  387. X    symp = get_symbol("MAKEFLAGS", 0);
  388. X    if (symp->svalue != NULL)
  389. X    {
  390. X        /* chop up the MAKEFLAGS and feed them to to make_args() */
  391. X
  392. X        envp = tstrcpy(symp->svalue);
  393. X        envv = tokenize(envp);
  394. X        for (i = 0; envv[i] != NULL; i++);
  395. X        make_args(i, envv);
  396. X
  397. X        /* free the vector of pointers, and the string itself, */
  398. X        /* since you cannot have macros, targets or makefiles  */
  399. X        /* in the MAKEFLAGS macro.                             */
  400. X
  401. X        tfree(envv);
  402. X        tfree(envp);
  403. X        tfree(makeflags);    /* ignore this, since we just read it */
  404. X    }
  405. X
  406. X    make_args(--argc, ++argv);    /* process command line options */
  407. X
  408. X    add_macro(makeflags, 0);/* update the MAKEFLAGS macro */
  409. X    tfree(makeflags);
  410. X
  411. X    /* add command line macros, so they DON'T get overridden */
  412. X
  413. X    for (i = 0; mlist[i] != NULL; i++)
  414. X        add_macro(mlist[i], 1);
  415. X
  416. X    tfree(mlist);        /* all done with macros */
  417. X
  418. X    if (opts.query)        /* -q never executes anything */
  419. X        opts.noexec = 1;
  420. X
  421. X    if (opts.noexec)
  422. X        opts.touch = 0;    /* -n never touches */
  423. X
  424. X    if (dispcount > 1)    /* display `default.mk' on -DD */
  425. X        opts.display = 1;
  426. X
  427. X    first_targ = NULL;    /* used in parse() */
  428. X
  429. X    if (readdef)        /* read in `default.mk' */
  430. X        parse(fopenp(MAKEINI, "r"));
  431. X
  432. X    if (dispcount > 0)    /* display makefile's on -D */
  433. X        opts.display = 1;
  434. X
  435. X    first_targ = NULL;    /* get first target in `makefile' */
  436. X
  437. X    /* parse the makefiles given on command line */
  438. X    for (i = 0; flist[i] != NULL; i++)
  439. X    {
  440. X        parse(equal(flist[i], "-") ? fdopen(dup(fileno(stdin)), "r")
  441. X              : fopen(flist[i], "r"));
  442. X    }
  443. X
  444. X    /* no makefiles specified, so use "makefile" or "Makefile" */
  445. X    if (i == 0)
  446. X    {
  447. X        if (parse(fopen("makefile", "r")) == 0)
  448. X        {
  449. X#ifndef    MSDOS
  450. X            parse(fopen("Makefile", "r"));
  451. X#endif
  452. X        }
  453. X    }
  454. X
  455. X    tfree(flist);        /* all done with makefile's */
  456. X
  457. X    /* find the current value of the $(MAKE) macro */
  458. X    symp = get_symbol("MAKE", 0);
  459. X    opts.make = (symp->svalue == NULL) ? "make" : symp->svalue;
  460. X
  461. X    /* get list of commands which will force usage of SHELL */
  462. X    symp = get_symbol("SHELLCMD", 0);
  463. X    shell_cmds = (symp->svalue) ? tokenize(tstrcpy(symp->svalue)) : NULL;
  464. X
  465. X    if ((targp = get_target(".INIT")) != NULL)
  466. X        build(targp->tshell);    /* process the .INIT rule */
  467. X
  468. X    mk = 0;
  469. X
  470. X    for (i = 0; tlist[i] != NULL; i++)
  471. X    {
  472. X        /* process command line arguments */
  473. X        mk |= (make(tlist[i], 1) > 0) ? 1 : 0;
  474. X    }
  475. X
  476. X    tfree(tlist);        /* all done with targets */
  477. X
  478. X    /* if no targets specified, make the first one */
  479. X    if (i == 0 && first_targ)
  480. X        mk |= (make(first_targ->tfile->fname, 1) > 0) ? 1 : 0;
  481. X
  482. X    if ((targp = get_target(".DONE")) != NULL)
  483. X        build(targp->tshell);    /* process the .DONE rule */
  484. X
  485. X    /* all done with the shell commands, so clean up */
  486. X    if (shell_cmds)
  487. X    {
  488. X        if (*shell_cmds)
  489. X            tfree(*shell_cmds);
  490. X        tfree(shell_cmds);
  491. X    }
  492. X
  493. X    return (mk & opts.query);    /* not exit(); see new_make() */
  494. X}
  495. X
  496. X
  497. X/*
  498. X * make_args    - process the command line arguments
  499. X */
  500. Xmake_args(argc, argv)
  501. Xint     argc;
  502. Xchar  **argv;
  503. X{
  504. X    int     tlen;
  505. X    int     flen;
  506. X    int     mlen;
  507. X    int     no_k = 0;    /* override the -k option */
  508. X    char   *tmf;
  509. X    int     addflag;
  510. X    fileptr    fp;
  511. X
  512. X    now = time(NULL);    /* get current date & time */
  513. X
  514. X    makeflags = tstrcpy("MAKEFLAGS+=");
  515. X
  516. X    tlen = flen = mlen = 0;
  517. X
  518. X    for (; argc != 0; ++argv, --argc)
  519. X    {
  520. X        if (**argv != '-')
  521. X        {
  522. X            /* doesn't start with '-'; must be macro or target */
  523. X
  524. X            if (strchr(*argv, '='))
  525. X            {    /* store as a macro */
  526. X                if (mlen == mmax)
  527. X                    mlist = grow_list(mlist, &mmax);
  528. X                mlist[mlen++] = *argv;
  529. X            }
  530. X            else
  531. X            {    /* store as a target */
  532. X                if (tlen == tmax)
  533. X                    tlist = grow_list(tlist, &tmax);
  534. X                tlist[tlen++] = *argv;
  535. X            }
  536. X            continue;
  537. X        }
  538. X
  539. X        /* must be an option */
  540. X
  541. X        tmf = tstrcat(makeflags, *argv);
  542. X
  543. X        while (*argv && *++*argv)
  544. X        {
  545. X            addflag = 1;    /* add to MAKEFLAGS */
  546. X            switch (**argv)
  547. X            {
  548. X            case 'b':    /* backwards compatibility */
  549. X            case '-':    /* SCO Xenix compatibility */
  550. X                addflag = 0;    /* don't add to MAKEFLAGS */
  551. X                break;
  552. X
  553. X            case 'd':    /* show dependencies */
  554. X                addflag = 0;    /* don't add to MAKEFLAGS */
  555. X                opts.depend++;
  556. X                break;
  557. X
  558. X            case 'D':    /* display makefiles */
  559. X                dispcount++;
  560. X                break;
  561. X
  562. X            case 'e':    /* don't override environment */
  563. X                opts.envirn = 1;
  564. X                break;
  565. X
  566. X            case 'f':    /* new makefile name */
  567. X                addflag = 0;    /* don't add to MAKEFLAGS */
  568. X                if (argc < 2)
  569. X                    usage();
  570. X                if (flen == fmax)
  571. X                    flist = grow_list(flist, &fmax);
  572. X                ++argv, --argc;
  573. X                flist[flen++] = *argv;
  574. X
  575. X                *argv = NULL;
  576. X                break;
  577. X
  578. X            case 'i':    /* ignore errors */
  579. X                opts.ignore = 1;
  580. X                break;
  581. X
  582. X            case 'k':    /* give up on current target on error */
  583. X                opts.keepon = 1;
  584. X                break;
  585. X
  586. X            case 'n':    /* don't execute commands */
  587. X                opts.noexec = 1;
  588. X                break;
  589. X
  590. X            case 'q':    /* question mode */
  591. X                opts.query = 1;
  592. X                break;
  593. X
  594. X            case 'r':    /* don't read default.mk */
  595. X                readdef = 0;
  596. X                break;
  597. X
  598. X            case 's':    /* don't echo commands */
  599. X                opts.silent = 1;
  600. X                break;
  601. X
  602. X            case 'S':    /* Undo -k option */
  603. X                no_k = 1;
  604. X                break;
  605. X
  606. X            case 't':    /* touch files, don't build */
  607. X                opts.touch = 1;
  608. X                break;
  609. X
  610. X            case 'W':    /* What-if file is touched? */
  611. X                if (argc < 2)
  612. X                    usage();
  613. X                ++argv, --argc;
  614. X                fp = add_file(*argv);
  615. X                fp->ftime = now;
  616. X
  617. X                *argv = NULL;
  618. X                break;
  619. X
  620. X            default:
  621. X                usage();    /* never returns */
  622. X            }
  623. X        }
  624. X
  625. X        if (addflag)
  626. X        {
  627. X            tfree(makeflags);
  628. X            makeflags = tstrcat(tmf, " ");
  629. X        }
  630. X
  631. X        tfree(tmf);
  632. X    }
  633. X
  634. X    /* terminate all lists with a NULL pointer */
  635. X
  636. X    tlist[tlen] = NULL;
  637. X    flist[flen] = NULL;
  638. X    mlist[mlen] = NULL;
  639. X
  640. X    /* check for -S over-riding -k option */
  641. X    if (no_k)
  642. X        opts.keepon = 0;
  643. X
  644. X    /* let the caller update the makeflags macro */
  645. X}
  646. X
  647. X
  648. X/*
  649. X * grow_list    - expand the list of pointers by a factor of two
  650. X */
  651. Xchar  **grow_list(list, len)
  652. Xchar  **list;
  653. Xint    *len;
  654. X{
  655. X    int     l;
  656. X
  657. X    /* if list is NULL, start off with a default list */
  658. X
  659. X    if (list == NULL)
  660. X        list = (char **) talloc(((l = 1) + 1) * sizeof(char *));
  661. X    else
  662. X    {
  663. X        l = *len;    /* get current length */
  664. X
  665. X        list = (char **) trealloc((char *) list,
  666. X                      ((l <<= 1) + 1) * sizeof(char *));
  667. X    }
  668. X
  669. X    if (list == NULL)
  670. X        terror(1, "too many options");
  671. X
  672. X    /* if we are initially allocating it, set first pointer to NULL */
  673. X
  674. X    if (l == 1)
  675. X        *list = NULL;
  676. X
  677. X    *len = l;        /* update current length */
  678. X    return (list);
  679. X}
  680. X
  681. X
  682. X/*
  683. X * fopenp    - open file in current directory or along PATH
  684. X */
  685. XFILE   *fopenp(fname, type)
  686. Xchar   *fname;
  687. Xchar   *type;
  688. X{
  689. X    int     len;
  690. X    char   *fpath;
  691. X    FILE   *fd;
  692. X    char   *path;
  693. X    char   *tp;
  694. X
  695. X    /* try to open file relative to current directory */
  696. X    if ((fd = fopen(fname, type)) != NULL)
  697. X        return (fd);
  698. X#ifndef    MSDOS
  699. X    /* didn't work, try home directory */
  700. X    if ((path = getenv("HOME")) != NULL)
  701. X    {
  702. X        fpath = talloc(strlen(path) + strlen(fname) + 2);
  703. X
  704. X        strcpy(fpath, path);
  705. X        len = strlen(fpath) - 1;
  706. X
  707. X        /* make sure there is a separator between path and filename */
  708. X
  709. X        if (!strchr(FILE_SEPARATOR, fpath[len]))
  710. X            fpath[++len] = '/';
  711. X
  712. X        strcpy(&fpath[len + 1], fname);    /* attach the filename */
  713. X        fd = fopen(fpath, type);
  714. X        tfree(fpath);
  715. X
  716. X        if (fd != NULL)
  717. X            return (fd);
  718. X    }
  719. X#endif
  720. X    /* didn't work, search along path */
  721. X
  722. X    if ((path = getenv("PATH")) == NULL)
  723. X        return (NULL);
  724. X
  725. X    path = tstrcpy(path);    /* allocate string and copy */
  726. X    fpath = talloc(strlen(path) + strlen(fname) + 2);
  727. X
  728. X    /* look for tokens separated by semi-colons (;) or colons (:) */
  729. X
  730. X    tp = token(path, PATH_SEPARATOR, NULL);
  731. X    while (tp != NULL)
  732. X    {
  733. X        strcpy(fpath, tp);
  734. X        len = strlen(fpath) - 1;
  735. X
  736. X        /* make sure there is a separator between path and filename */
  737. X
  738. X        if (!strchr(FILE_SEPARATOR, fpath[len]))
  739. X            fpath[++len] = '/';
  740. X
  741. X        strcpy(&fpath[len + 1], fname);    /* attach the filename */
  742. X        if ((fd = fopen(fpath, type)) != NULL)
  743. X            break;
  744. X
  745. X        tp = token(NULL, PATH_SEPARATOR, NULL);
  746. X    }
  747. X
  748. X    tfree(path);
  749. X    tfree(fpath);
  750. X
  751. X    return (fd);
  752. X}
  753. X
  754. X
  755. X/*
  756. X * make        - guts of the make command
  757. X *        - make all pre-requisites, and if necessary, build target
  758. X *
  759. X *    returns    -1 target was already up to date w.r.t. pre-requisites
  760. X *         0 target has not been built
  761. X *         1 target is now built (and up to date)
  762. X */
  763. Xmake(targname, worry)
  764. Xchar   *targname;
  765. Xint     worry;            /* if set, it is an error to NOT build this */
  766. X{
  767. X    targptr targp;
  768. X    fileptr *preqp;
  769. X    int     mk;
  770. X    fileptr filep;
  771. X    long    targtime;
  772. X    long    preqtime;
  773. X    char   *dol_quest;
  774. X    char   *dq;
  775. X
  776. X    mk = 0;
  777. X
  778. X    /* if recorded time of file is not default, we've already built it */
  779. X    filep = get_file(targname);
  780. X    if (filep && filep->ftime != MAXNEGTIME)
  781. X        return (1);
  782. X
  783. X    targp = get_target(targname);    /* find the target node */
  784. X    if (targp == NULL)
  785. X        return (default_rule(targname, NULL, worry, 0));
  786. X
  787. X    /* keep actual time of current target */
  788. X    targtime = file_time(targname, 0);
  789. X
  790. X    /* must build non-existant files, even with no pre-requisites */
  791. X    preqtime = MAXNEGTIME + 1;
  792. X
  793. X    dol_quest = tstrcpy("");
  794. X
  795. X    /* make all pre-requisites */
  796. X    preqp = targp->tpreq;
  797. X    while (preqp && *preqp)
  798. X    {
  799. X        mk |= make((*preqp)->fname, worry);
  800. X
  801. X        /* keep track of newest pre-requisite */
  802. X        if (preqtime < (*preqp)->ftime)
  803. X            preqtime = (*preqp)->ftime;
  804. X
  805. X        if (targtime < (*preqp)->ftime)
  806. X        {
  807. X            dq = tstrcat(dol_quest, (*preqp)->fname);
  808. X            tfree(dol_quest);
  809. X            dol_quest = tstrcat(dq, " ");
  810. X            tfree(dq);
  811. X        }
  812. X
  813. X        /* display as necessary */
  814. X        if (opts.depend > 1 ||
  815. X            (opts.depend && (*preqp)->ftime > targtime))
  816. X        {
  817. X            display_prereq(targname, targtime, (*preqp)->fname,
  818. X                       (*preqp)->ftime);
  819. X        }
  820. X
  821. X        ++preqp;
  822. X    }
  823. X
  824. X    add_symbol("?", dol_quest, 0);
  825. X    tfree(dol_quest);
  826. X
  827. X    if (targp->tshell == NULL)    /* try default rules anyway */
  828. X    {
  829. X        if (default_rule(targname, targp, 0, preqtime > targtime))
  830. X            return (1);
  831. X        return (mk);
  832. X    }
  833. X    else
  834. X    if (preqtime > targtime)
  835. X    {
  836. X        if (opts.touch)    /* won't be set when `noexec' */
  837. X            touch_file(targname);
  838. X        else
  839. X        {
  840. X            add_metas("", "", targname);
  841. X            if (build(targp->tshell))
  842. X                return (0);
  843. X        }
  844. X
  845. X        targp->tfile->ftime = (opts.noexec) ? now
  846. X            : file_time(targname, 1);
  847. X        return (1);
  848. X    }
  849. X
  850. X    targp->tfile->ftime = targtime;
  851. X
  852. X    return (mk);
  853. X}
  854. X
  855. X
  856. X/*
  857. X * default_rule    - try the .SUFFIXES when we don't have an explicit target
  858. X *        - if `worry' is set, it is an ERROR to NOT build this target
  859. X *        - `mustbuild' is set if make() has out-of-date prereq's
  860. X *           but no explicit shell rules
  861. X */
  862. Xdefault_rule(targname, targetp, worry, mustbuild)
  863. Xchar   *targname;
  864. Xtargptr targetp;
  865. Xint     worry;
  866. Xint     mustbuild;
  867. X{
  868. X    targptr targp;
  869. X    fileptr *preqp;
  870. X    fileptr filep;
  871. X    char   *ext;
  872. X    char   *basename;
  873. X    char   *preqname;
  874. X    long    targtime;
  875. X    long    preqtime;
  876. X    int     built;
  877. X    char    suffrule[80];
  878. X
  879. X    ext = strrchr(targname, '.');    /* find the extension */
  880. X    if (ext == NULL)
  881. X        ext = targname + strlen(targname);
  882. X
  883. X    basename = tstrncpy(targname, ext - targname);    /* find the base name */
  884. X
  885. X    targtime = file_time(targname, 0);
  886. X
  887. X    /* suffix_targ is used to (slightly) speed up this function */
  888. X    preqp = suffix_targ ? suffix_targ->tpreq : NULL;
  889. X    built = 0;
  890. X
  891. X    while (preqp && *preqp && !built)
  892. X    {
  893. X        /* look for a default rule from SUFFIX to `ext' */
  894. X        strcat(strcpy(suffrule, (*preqp)->fname), ext);
  895. X        targp = get_target(suffrule);    /* e.g. `.c.o' */
  896. X
  897. X        if (targp != NULL)
  898. X        {
  899. X            /* found a rule; see if file exists */
  900. X            preqname = get_preqname(targetp, (*preqp)->fname,
  901. X                        basename);
  902. X            preqtime = file_time(preqname, 0);
  903. X
  904. X            /*
  905. X             * don't bother recursive makes unless necessary e.g.
  906. X             * we have .c.o and .l.c, but also .l.o! we want to
  907. X             * use .l.o if a .c file does not exist 
  908. X             */
  909. X            if (preqtime != MAXNEGTIME || mustbuild)
  910. X                built = make(preqname, 0);
  911. X
  912. X            /* check if pre-req file exists and is newer */
  913. X            preqtime = file_time(preqname, 0);
  914. X            if (preqtime > targtime || (mustbuild && built))
  915. X            {
  916. X                if (opts.depend)
  917. X                {
  918. X                    display_prereq(targname, targtime,
  919. X                               preqname, preqtime);
  920. X                }
  921. X
  922. X                if (opts.touch)    /* won't be set when `noexec' */
  923. X                    touch_file(targname);
  924. X                else
  925. X                {
  926. X                    add_metas(basename, preqname, targname);
  927. X                    if (build(targp->tshell))
  928. X                        return (0);
  929. X                }
  930. X                built = 1;
  931. X            }
  932. X            else
  933. X            if (opts.depend > 1 && preqtime != MAXNEGTIME)
  934. X            {
  935. X                display_prereq(targname, targtime,
  936. X                           preqname, preqtime);
  937. X            }
  938. X
  939. X            tfree(preqname);
  940. X        }
  941. X
  942. X        ++preqp;    /* try next .SUFFIXES rule */
  943. X    }
  944. X
  945. X    if (!built)
  946. X    {
  947. X        /* didn't find anything; try the default rule */
  948. X        targp = get_target(".DEFAULT");
  949. X        if (targp != NULL)
  950. X        {
  951. X            add_metas(basename, "", targname);
  952. X            if (build(targp->tshell))
  953. X                return (0);
  954. X            built = 1;
  955. X        }
  956. X        else
  957. X        if (targtime == MAXNEGTIME && worry)
  958. X            terror(1, tstrcat("Don't know how to make ", targname));
  959. X    }
  960. X
  961. X    tfree(basename);
  962. X
  963. X    /* record the current file time */
  964. X    if ((filep = get_file(targname)) != NULL)
  965. X    {
  966. X        filep->ftime = (built == 1 && opts.noexec) ? now
  967. X            : file_time(targname, 1);
  968. X    }
  969. X
  970. X    return (built ? built : ((targtime == MAXNEGTIME) ? 0 : 1));
  971. X}
  972. X
  973. X
  974. X/*
  975. X * get_preqname - find prerequisite name from target and prerequisite suffix
  976. X */
  977. Xchar   *get_preqname(targp, suffix, basename)
  978. Xtargptr targp;
  979. Xchar   *suffix;
  980. Xchar   *basename;
  981. X{
  982. X    fileptr *preqp;
  983. X    char   *preqf;
  984. X    char   *basef;
  985. X    int     i;
  986. X
  987. X    if (targp != NULL)
  988. X    {
  989. X        /* strip the directory name from the basename */
  990. X        basef = tsplit(basename, FILE_SEPARATOR, NULL);
  991. X
  992. X        /* look through prerequisite list for file with right name */
  993. X        for (preqp = targp->tpreq; preqp && *preqp; ++preqp)
  994. X        {
  995. X            /* split the pre-requisite into dir and filenames */
  996. X            preqf = tsplit((*preqp)->fname, FILE_SEPARATOR, NULL);
  997. X
  998. X            /* see if the filename part matches the target */
  999. X            for (i = 0; preqf[i] != '\0'; i++)
  1000. X            {
  1001. X                if (preqf[i] != basef[i])
  1002. X                    break;
  1003. X            }
  1004. X
  1005. X            /* if we differed only on the suffix, we're okay */
  1006. X            if (strcmp(preqf + i, suffix) == 0)
  1007. X                return (tstrcpy((*preqp)->fname));
  1008. X        }
  1009. X#ifdef    ALL_PREQS
  1010. X        /* didn't find a matching basename + suffix in the preq-list. */
  1011. X        /* look through prerequisite list for file with right suffix. */
  1012. X        for (preqp = targp->tpreq; preqp && *preqp; ++preqp)
  1013. X        {
  1014. X            preqf = strrchr((*preqp)->fname, '.');
  1015. X            if (preqf == NULL)
  1016. X                continue;
  1017. X
  1018. X            /* take the first file which has right suffix */
  1019. X            if (strcmp(suffix, preqf) == 0)
  1020. X                return (tstrcpy((*preqp)->fname));
  1021. X        }
  1022. X#endif                /* ALL_PREQS */
  1023. X    }
  1024. X
  1025. X    /* didn't find one, so try forming one using basename + suffix */
  1026. X
  1027. X    return (tstrcat(basename, suffix));
  1028. X}
  1029. X
  1030. X
  1031. X/*
  1032. X * add_metas    - add symbols for $*, $< and $@
  1033. X */
  1034. Xadd_metas(basename, preqname, targname)
  1035. Xchar   *basename;
  1036. Xchar   *preqname;
  1037. Xchar   *targname;
  1038. X{
  1039. X    /* $* is the basename */
  1040. X    add_symbol("*", basename, 0);
  1041. X    split_meta("*", basename);
  1042. X
  1043. X    add_symbol("<", preqname, 0);
  1044. X    split_meta("<", preqname);
  1045. X
  1046. X    add_symbol("@", targname, 0);
  1047. X    split_meta("@", targname);
  1048. X}
  1049. X
  1050. X
  1051. X/*
  1052. X * split_meta -    split a metasymbol into Directory and File parts
  1053. X */
  1054. Xsplit_meta(sym, name)
  1055. Xchar   *sym;
  1056. Xchar   *name;
  1057. X{
  1058. X    char   *dname;
  1059. X    char   *dsym;
  1060. X    char   *fsym;
  1061. X
  1062. X    /* construct the macro names (e.g. $(*D), $(@F)) */
  1063. X    dsym = tstrcat(sym, "D");
  1064. X    fsym = tstrcat(sym, "F");
  1065. X
  1066. X    add_symbol(fsym, tsplit(name, FILE_SEPARATOR, &dname), 0);
  1067. X
  1068. X    if (dname == NULL)
  1069. X        add_symbol(dsym, ".", 0);
  1070. X    else
  1071. X    {
  1072. X        add_symbol(dsym, dname, 0);
  1073. X        tfree(dname);
  1074. X    }
  1075. X
  1076. X    tfree(dsym);
  1077. X    tfree(fsym);
  1078. X}
  1079. X
  1080. X
  1081. X/*
  1082. X * touch_file    - set the MODIFICATION time of the file to NOW
  1083. X */
  1084. Xtouch_file(targname)
  1085. Xchar   *targname;
  1086. X{
  1087. X    int     handle;
  1088. X#ifndef    MSDOS
  1089. X    time_t  timep[2];
  1090. X
  1091. X    time(&timep[0]);
  1092. X    timep[1] = timep[0];
  1093. X    handle = utime(targname, timep);
  1094. X#else
  1095. X    handle = utime(targname, NULL);
  1096. X#endif
  1097. X    fputs("touch ", stdout);
  1098. X    puts(targname);
  1099. X
  1100. X    if (handle == 0)
  1101. X        return;
  1102. X
  1103. X    /* create the file, if it did not exist */
  1104. X    if (errno == ENOENT)
  1105. X    {
  1106. X        handle = open(targname, O_CREAT | O_TRUNC, S_IWRITE);
  1107. X        if (handle != -1)
  1108. X        {
  1109. X            close(handle);
  1110. X            return;
  1111. X        }
  1112. X    }
  1113. X
  1114. X    perror("touch");
  1115. X    exit(1);
  1116. X}
  1117. X
  1118. Xdisplay_prereq(targname, targtime, preqname, preqtime)
  1119. Xchar   *targname;
  1120. Xlong    targtime;
  1121. Xchar   *preqname;
  1122. Xlong    preqtime;
  1123. X{
  1124. X#ifdef    MSDOS
  1125. X    char    chtime[10];
  1126. X
  1127. X    fputs(targname, stdout);
  1128. X    fputs(" (", stdout);
  1129. X    fputs(ltoa(targtime, chtime, 16), stdout);
  1130. X    fputs((targtime <= preqtime) ? ") older than " : ") newer than ", stdout);
  1131. X    fputs(preqname, stdout);
  1132. X    fputs(" (", stdout);
  1133. X    fputs(ltoa(preqtime, chtime, 16), stdout);
  1134. X    puts(")");
  1135. X#else
  1136. X    printf("%s (%08lx) %s than %s (%08lx)\n",
  1137. X           targname, targtime,
  1138. X           (targtime < preqtime) ? "older" : "newer",
  1139. X           preqname, preqtime);
  1140. X#endif
  1141. X}
  1142. X
  1143. X
  1144. Xlong    file_time(fname, built)
  1145. Xchar   *fname;
  1146. Xint     built;
  1147. X{
  1148. X    struct stat sbuf;
  1149. X
  1150. X    /*
  1151. X     * if the file is supposedly built, but still does not exists, just
  1152. X     * fake it by returning the current time. 
  1153. X     */
  1154. X    if (stat(fname, &sbuf) != 0)
  1155. X        return (built ? now : MAXNEGTIME);
  1156. X    return (sbuf.st_mtime);
  1157. X}
  1158. X
  1159. X
  1160. Xusage()
  1161. X{
  1162. X    puts("make [-f file] [-dDiknqrsStWb-] [target ...] [macro=value ...]");
  1163. X    exit(1);
  1164. X}
  1165. END_OF_FILE
  1166. if test 18624 -ne `wc -c <'make.c'`; then
  1167.     echo shar: \"'make.c'\" unpacked with wrong size!
  1168. fi
  1169. # end of 'make.c'
  1170. fi
  1171. if test -f 'make.doc' -a "${1}" != "-c" ; then 
  1172.   echo shar: Will not clobber existing file \"'make.doc'\"
  1173. else
  1174. echo shar: Extracting \"'make.doc'\" \(19978 characters\)
  1175. sed "s/^X//" >'make.doc' <<'END_OF_FILE'
  1176. XNAME
  1177. X     make - maintain, update, and reconstruct groups of programs
  1178. X
  1179. XSYNOPSIS
  1180. X     make [-f file] [-dDeiknqrsStWb-] [target...] [macro=value ...]
  1181. X
  1182. XDESCRIPTION
  1183. X     MAKE takes a file of dependencies (a 'makefile') and decides what
  1184. X     commands have to be executed to bring the files up to date.  These
  1185. X     commands are either executed directly from MAKE or written to the
  1186. X     standard output without executing them.
  1187. X
  1188. X     If no makefile is specified with a -f option, MAKE reads a file
  1189. X     named `makefile', if it exists.
  1190. X
  1191. X     If no target is specified on the command line, MAKE uses the first
  1192. X     target defined in the first makefile.
  1193. X
  1194. XOPTIONS
  1195. X     -f makefile
  1196. X         Use the description file `makefile'.  A - as the makefile
  1197. X         argument denotes the standard input.
  1198. X
  1199. X     -d  Display the reasons why MAKE chooses to rebuild a target.  All
  1200. X         dependencies which are newer are displayed
  1201. X
  1202. X     -dd Display the dependency checks in more detail.  Dependencies
  1203. X         which are older are displayed, as well as newer.
  1204. X
  1205. X     -D  Display the text of the makefiles as read in.
  1206. X
  1207. X     -DD Display the text of the makefiles and `default.mk'.
  1208. X
  1209. X     -e  Let environment variables override macro definitions from
  1210. X         makefiles.  Normally, makefile macros override environment
  1211. X         variables.  Command line macro definitions always override both
  1212. X         environment variables and makefile macros definitions.
  1213. X
  1214. X     -i  Ignore error codes returned by commands.  This is equivalent to
  1215. X         the special target .IGNORE:.
  1216. X
  1217. X     -k  When a nonzero error status is returned by a command, abandon
  1218. X         work on the current target, but continue with other branches
  1219. X         that do not depend on this target.
  1220. X
  1221. X     -n  No execution mode.  Print commands, but do not execute them.
  1222. X         Even lines beginning with an @ are printed.  However, if a
  1223. X         command line is an invocation of MAKE, that line is always
  1224. X         executed.
  1225. X
  1226. X     -q  Question mode.  MAKE returns a zero or non-zero status code,
  1227. X         depending on whether or not the target file is up to date.
  1228. X
  1229. X     -r  Do not read in the default file `default.mk'.
  1230. X
  1231. X     -s  Silent mode.  Do not print command lines before executing them.
  1232. X         This is equivalent to the special target .SILENT:.
  1233. X
  1234. X     -S  Undo the effect of the -k option.  Stop processing when a
  1235. X         non-zero exit status is returned by a command.
  1236. X
  1237. X     -t  Touch the target files, bringing them up to date, rather than
  1238. X         performing the rules to reconstruct them.
  1239. X
  1240. X     -W target
  1241. X         Perform the make as if this target has a modification time of
  1242. X         "right now".  This is the "What If?" option.
  1243. X
  1244. X     -b  This option is accepted and ignored.  It allows compatibility
  1245. X         with older makefiles (and scripts).
  1246. X
  1247. X     --  This option is accepted and ignored.  It allows compatibility
  1248. X         with SCO Xenix which requires -$(MAKEFLAGS).  This version of
  1249. X         make includes a '-' within $(MAKEFLAGS).
  1250. X
  1251. X     macro=value
  1252. X         Macro definition.  This definition remains fixed for the MAKE
  1253. X         invocation.  It overrides any regular definitions for the
  1254. X         specified macro within the makefiles and from the environment.
  1255. X         It is inherited by subordinate MAKE's but act as an environment
  1256. X         variable for these.  That is, depending on the -e setting, it
  1257. X         may be overridden by a makefile definition.
  1258. X
  1259. XUSAGE
  1260. X  Makefiles
  1261. X     The first makefile read is `default.mk', which can be located any-
  1262. X     where along the PATH.  It typically contains predefined macros and
  1263. X     implicit rules.  For non-DOS systems (e.g.  Unix), it is searched
  1264. X     for in the current directory, then in the users home directory, and
  1265. X     finally along the PATH.
  1266. X
  1267. X     The default name of the makefile is `makefile' in the current
  1268. X     directory.  If this file is not found on a non-DOS system, the file
  1269. X     `Makefile' is then used as the default.  Alternate makefiles can be
  1270. X     specified using one or more '-f' options on the command line.
  1271. X     Multiple '-f's act as the concatenation of all the makefiles in a
  1272. X     left-to-right order.
  1273. X
  1274. X     The makefile(s) may contain a mixture of comment lines, macro
  1275. X     definitions, include lines, and target lines.  Lines may be
  1276. X     continued across input lines by escaping the NEWLINE with a
  1277. X     backslash (\).
  1278. X
  1279. X     Anything after a "#" is considered to be a comment, and is stripped
  1280. X     from the line, including spaces immediately before the "#.  If the
  1281. X     "#" is inside a quoted string, it is not treated as a comment.
  1282. X     Completely blank lines are ignored.
  1283. X
  1284. X     An include line is used to include the text of another makefile.
  1285. X     It consists of the word "include" left justified, followed by
  1286. X     spaces, and followed by the name of the file that is to be included
  1287. X     at this line.  Macros in the name of the included file are expanded
  1288. X     before the file is included.  Include files may be nested.
  1289. X
  1290. X  Macros
  1291. X     Macros have the form `WORD = text and more text'.  The WORD need
  1292. X     not be uppercase, but this is an accepted standard.  Later lines
  1293. X     which contain $(WORD) or ${WORD} will have this replaced by `text
  1294. X     and more text'.  If the macro name is a single character, the
  1295. X     parentheses are optional.  Note that the expansion is done
  1296. X     recursively, so the body of a macro may contain other macro
  1297. X     invocations.
  1298. X
  1299. X    e.g.    FLINTSTONES = wilma and fred
  1300. X        RUBBLES = barney and betty
  1301. X        BEDROCK = $(FLINTSTONES) and $(RUBBLES)
  1302. X
  1303. X     `$(BEDROCK)' becomes `wilma and fred and barney and betty'
  1304. X
  1305. X     Also note that whitespace around the equal sign is not relevant
  1306. X     when defining a macro.  The following four macro definitions are
  1307. X     all equivalent:
  1308. X
  1309. X        MACRO = body
  1310. X        MACRO=  body
  1311. X        MACRO  =body
  1312. X        MACRO=body
  1313. X
  1314. X     Macros may be added to by using the `+=' notation.  Thus
  1315. X
  1316. X        FLINTSTONES += and pebbles and dino
  1317. X
  1318. X     would be (given the examples above) the same as
  1319. X
  1320. X        FLINTSTONES = wilma and fred and pebbles and dino
  1321. X
  1322. X  Special Macros
  1323. X     MAKE
  1324. X         This normally has the value "make".  Any line which invokes
  1325. X         MAKE temporarily overrides the -n option, just for the duration
  1326. X         of the one line.  This allows nested invocations of MAKE to be
  1327. X         tested with the -n option.
  1328. X
  1329. X     MAKEFLAGS
  1330. X         This macro has the set of options provided to MAKE as its
  1331. X         value.  If this is set as an environment variable, the set of
  1332. X         options is processed before any command line options.  This
  1333. X         macro may be explicitly passed to nested MAKEs, but it is also
  1334. X         available to these invocations as an environment variable.  The
  1335. X         -f and -d flags are not recorded in this macro.
  1336. X
  1337. X     SUFFIXES
  1338. X         This contains the default list of suffixes supplied to the
  1339. X         special target .SUFFIXES:.  It is not sufficient to simply
  1340. X         change this macro in order to change the .SUFFIXES: list.  That
  1341. X         target must be specified in your makefile.
  1342. X
  1343. X     SHELLCMD
  1344. X         This contains the default list of commands which are local to
  1345. X         the SHELL.  If a rule is an invocation of one of these
  1346. X         commands, a SHELL is automatically spawned to handle it.
  1347. X
  1348. X     $   This macro translates to a dollar sign.  Thus you can use "$$"
  1349. X         in the makefile to represent a single "$".
  1350. X
  1351. X     There are several dynamically maintained macros that are useful as
  1352. X     abbreviations within rules.  It is best not to define them
  1353. X     explicitly.
  1354. X
  1355. X     $*  The basename of the current target.
  1356. X
  1357. X     $<  The name of the current dependency file.
  1358. X
  1359. X     $@  The name of the current target.
  1360. X
  1361. X     $?  The names of dependents which are younger than the target.
  1362. X
  1363. X     The $< and $* macros are normally used for implicit rules.  They
  1364. X     may be unreliable when used within explicit target command lines.
  1365. X     These may be suffixed with D and F, to specify the Directory and
  1366. X     Filename components (e.g. ${*D}, ${@F}).  If there is no directory
  1367. X     in the name, "." is supplied.
  1368. X
  1369. X  Targets
  1370. X     A target entry in the makefile has the following format:
  1371. X
  1372. X    target ... : [dependency ...] [; rule]
  1373. X        [rule]
  1374. X        ...
  1375. X
  1376. X     Any line which does not have leading whitespace (other than macro
  1377. X     definitions) is a `target' line.  Target lines consist of one or
  1378. X     more filenames (or macros which expand into same) called targets,
  1379. X     followed by a colon (:).  The ':' is followed by a list of
  1380. X     dependent files.  The dependency list may be terminated with a
  1381. X     semicolon (;) which may be followed by a rule or shell command.
  1382. X
  1383. X     Special allowance is made on MSDOS for the colons which are needed
  1384. X     to specify files on other drives, so for example, the following
  1385. X     will work as intended:
  1386. X
  1387. X        c:foo.bar : a:fee.ber
  1388. X
  1389. X     If a target is named in more than one target line, the dependencies
  1390. X     and rules are added to form the target's complete dependency list
  1391. X     and rule list.
  1392. X
  1393. X     The dependents are ones from which a target is constructed.  They
  1394. X     in turn may be targets of other dependents.  In general, for a
  1395. X     particular target file, each of its dependent files is `made', to
  1396. X     make sure that each is up to date with respect to it's dependents.
  1397. X
  1398. X     The modification time of the target is compared to the modification
  1399. X     times of each dependent file.  If the target is older, one or more
  1400. X     of the dependents have changed, so the target must be constructed.
  1401. X     Of course, this checking is done recursively, so that all
  1402. X     dependents of dependents of dependents of ...  are up to date.
  1403. X
  1404. X     To reconstruct a target, MAKE expands macros, strips off initial
  1405. X     whitespace, and either executes the rules directly, or passes each
  1406. X     to a shell or COMMAND.COM for execution.
  1407. X
  1408. X     For target lines, macros are expanded on input.  All other lines
  1409. X     have macro expansion delayed until absolutely required.
  1410. X
  1411. X  Special Targets
  1412. X     .DEFAULT:
  1413. X         The rule for this target is used to process a target when there
  1414. X         is no other entry for it, and no implicit rule for building it.
  1415. X         MAKE ignores all dependencies for this target.
  1416. X
  1417. X     .DONE:
  1418. X         This target and its dependencies are processed after all other
  1419. X         targets are built.
  1420. X
  1421. X     .IGNORE:
  1422. X         Non-zero error codes returned from commands are ignored.
  1423. X         Encountering this in a makefile is the same as specifying -i on
  1424. X         the command line.
  1425. X
  1426. X     .INIT:
  1427. X         This target and its dependencies are processed before any other
  1428. X         targets are processed.
  1429. X
  1430. X     .SILENT:
  1431. X         Commands are not echoed before executing them.  Encountering
  1432. X         this in a makefile is the same as specifying -s on the command
  1433. X         line.
  1434. X
  1435. X     .SUFFIXES:
  1436. X         The suffixes list for selecting implicit rules.  Specifying
  1437. X         this target with dependents adds these to the end of the
  1438. X         suffixes list.  Specifying it with no dependents clears the
  1439. X         list.  In order to add your own dependents to the head of the
  1440. X         list, you could enter:
  1441. X
  1442. X        .SUFFIXES:
  1443. X        .SUFFIXES:    .abc $(SUFFIXES)
  1444. X
  1445. X  Rules
  1446. X     A line in a makefile that starts with a TAB or SPACE is a shell
  1447. X     line or rule.  This line is associated with the most recently
  1448. X     preceding dependency line.  A sequence of these may be associated
  1449. X     with a single dependency line.  When a target is out of date with
  1450. X     respect to a dependent, the sequence of commands is executed.
  1451. X     Shell lines may have any combination of the following characters to
  1452. X     the left of the command:
  1453. X
  1454. X     @   will not echo the command line, except if -n is used.
  1455. X
  1456. X     -   MAKE will ignore the exit code of the command, i.e.  the
  1457. X         ERRORLEVEL of MSDOS.  Without this, MAKE terminates when a
  1458. X         nonzero exit code is returned.
  1459. X
  1460. X     +   MAKE will use a shell or COMMAND.COM to execute the command.
  1461. X
  1462. X     If the '+' is not attached to a shell line, but the command is a
  1463. X     DOS command or if redirection is used (<, |, >), the shell line is
  1464. X     passed to COMMAND.COM anyway.  For Unix, redirection, backquote (`)
  1465. X     parentheses and variables ($vname) force the use of a shell.
  1466. X
  1467. X     For DOS, inline stdin (<<) operator is emulated with a temporary
  1468. X     file.  That is, subsequent commands are written to a temporary
  1469. X     file, and the name of the temporary file is placed in the command
  1470. X     line.  For example, if you want to link a number of objects
  1471. X     together, you can have a rule such as
  1472. X
  1473. X         link $(OBJS),$(NAME),$(LDFLAGS),$(LIBS)
  1474. X
  1475. X     If the resulting command line (after expansion) is greater than
  1476. X     128, you can specify in the following manner.
  1477. X
  1478. X    link @<<END_OF_LINK
  1479. X        $(OBJS)
  1480. X        $(NAME)
  1481. X        $(LDFLAGS)
  1482. X        $(LIBS)
  1483. X    END_OF_LINK
  1484. X
  1485. X     The four lines between the tags (END_OF_LINK) are written to a
  1486. X     temporary file (e.g.  "\mk2"), and the command line is rewritten as
  1487. X     "link @\mk2".
  1488. X
  1489. X     The rules for redirection and tags are as follows:
  1490. X
  1491. X        1)  If the redirector (<<) is immediately followed by some text,
  1492. X            the text is used as the tag.  E.g.  "<<END_OF_LINK".
  1493. X
  1494. X        2)  If the redirector is not immediately followed by some text,
  1495. X            the next token is used as the tag.  E.g.  "<< END_OF_LINK".
  1496. X
  1497. X        3)  If the redirector is the last token on a line, there is no
  1498. X            tag.
  1499. X
  1500. X        4)  Lines immediately following the command are written to a
  1501. X            temporary file, until a line beginning with the tag is
  1502. X            encountered or until the end of the current set of rules.
  1503. X
  1504. X      The following are all equivalent.
  1505. X
  1506. X    link @<<        link @<<END_OF_LINK    link @<<END_OF_LINK
  1507. X        $(OBJS)            $(OBJS)            $(OBJS)
  1508. X        $(PROG)            $(PROG)            $(PROG)
  1509. X        $(LDFLAGS)        $(LDFLAGS)        $(LDFLAGS)
  1510. X        $(LIBS)            $(LIBS)            $(LIBS)
  1511. X                END_OF_LINK
  1512. X
  1513. X  Implicit Rules
  1514. X     Implicit rules are intimately tied to the .SUFFIXES: special
  1515. X     target.  Each entry in the .SUFFIXES defines an extension to a
  1516. X     filename which may be used to build another file.  The implicit
  1517. X     rules then define how to actually build one file from another.
  1518. X     These files are related, in that they must share a common basename,
  1519. X     but have different extensions.
  1520. X
  1521. X     If a file that is being made does not have an explicit target line,
  1522. X     an implicit rule is looked for.  Each entry in the .SUFFIXES: list
  1523. X     is combined with the extension of the target, to get the name of an
  1524. X     implicit target.  If this target exists, it gives the rules used to
  1525. X     transform a file with the dependent extension to the target file.
  1526. X     Any dependents of the implicit target are ignored.
  1527. X
  1528. X     In the following example, the .SUFFIXES: list is .c .y .l, and the
  1529. X     target file is fred.o which does not have a target line.  An
  1530. X     implicit rule target `.c.o' is constructed and searched for.  If it
  1531. X     does not exist, the next suffix is tried.  If the implicit rule
  1532. X     target does exist, MAKE looks for a file `fred.c'.  If this file
  1533. X     does not exist, the next extension is tried.  If `fred.c' does
  1534. X     exist, then the associated rules are executed to create fred.o from
  1535. X     fred.c, presumably invoking the C compiler.
  1536. X
  1537. X     If the next extension must be tried, MAKE reiterates the above with
  1538. X     target `.y.o' and a file named `fred.y', and potentially with
  1539. X     `.l.o' and `fred.l'.
  1540. X
  1541. X     If a file that is being made has an explicit target, but no rules,
  1542. X     a similar search is made for implicit rules.  Each entry in the
  1543. X     .SUFFIXES: list is combined with the extension of the target, to
  1544. X     get the name of an implicit target.  If such a target exists, then
  1545. X     the list of dependents is searched for a file with the correct
  1546. X     extension, and the implicit rules are invoked to create the target.
  1547. X
  1548. XEXAMPLES
  1549. X     This makefile says that pgm.exe depends on two files a.obj and
  1550. X     b.obj, and that they in turn depend on their corresponding source
  1551. X     files (a.c and b.c) along with the common file incl.h.
  1552. X
  1553. X    pgm.exe: a.obj b.obj
  1554. X        $(CC) a.obj b.obj -o $@
  1555. X
  1556. X    a.obj:    incl.h a.c
  1557. X        $(CC) -c a.c
  1558. X
  1559. X    b.obj:    incl.h b.c
  1560. X        $(CC) -c b.c
  1561. X
  1562. X     The following makefile uses implicit rules to express the same
  1563. X     dependencies.
  1564. X
  1565. X    pgm.exe: a.obj b.obj
  1566. X        $(CC) a.obj b.obj -o $@
  1567. X
  1568. X    a.obj b.obj: incl.h
  1569. X
  1570. X     This final makefile uses implicit rules to create targets with
  1571. X     dependencies in a different directory.  Note: this cannot be done
  1572. X     with standard Unix make.
  1573. X
  1574. X    pgm.exe: a.obj b.obj
  1575. X        $(CC) a.obj b.obj -o $@
  1576. X
  1577. X    a.obj:    incl.h ../a.c
  1578. X
  1579. X    b.obj:    incl.h ../b.c
  1580. X
  1581. XFILES
  1582. X     makefile            Current version(s) of make description file.
  1583. X     Makefile            Alternative to makefile, for Unix.
  1584. X     default.mk          Default file for user-defined targets, macros,
  1585. X                         and implicit rules.
  1586. X
  1587. XDIAGNOSTICS
  1588. X     MAKE returns an exit status of 1 when it halts as a result of an
  1589. X     error.  Otherwise it returns an exit status of 0.
  1590. X
  1591. X     Badly formed macro
  1592. X         A macro definition has been encountered which has incorrect
  1593. X         syntax.  Most likely, the name is missing.
  1594. X
  1595. X     cannot open file
  1596. X         The makefile indicated in an include directive was not found or
  1597. X         was not accessible.
  1598. X
  1599. X     Don't know how to make target
  1600. X         There is no makefile entry for target, none of MAKE's implicit
  1601. X         rules apply, and there is no .DEFAULT: rule.
  1602. X
  1603. X     Improper Macro.
  1604. X         An error has occurred during macro expansion.  The most likely
  1605. X         error is a missing closing bracket.
  1606. X
  1607. X     Macro too long (limit 100 chars):
  1608. X         A macro name is too long for the internal buffer.  Try shortening
  1609. X     it to 100 characters or less.
  1610. X
  1611. X     rules must be after target
  1612. X         A makefile syntax error, where a line beginning with a SPACE or
  1613. X         TAB has been encountered before a target line.
  1614. X
  1615. X     too many options
  1616. X         MAKE has run out of allocated space while processing command
  1617. X         line options or a target list.
  1618. X
  1619. X     Too many rules defined for target
  1620. X     A target occurs multiple times, and each time has rules.  A
  1621. X     target may only have one set of rules.
  1622. X
  1623. X     Unexpected end of line seen
  1624. X         A target line without a colon has been encountered.
  1625. X
  1626. XAUTHOR
  1627. X     Greg Yachuk      Informix Software Inc., Menlo Park, CA 92025
  1628. X     greggy@informix.com | {uunet,pyramid}!infmx!greggy    (415) 926-6300
  1629. X
  1630. X     Parts of this program are based on the work by Larry Campbell of
  1631. X     DEC, Mike Hickey of University of DC, and by Dan Grayson.
  1632. X
  1633. X     Some of this documentation is based on text written by Jeffrey
  1634. X     Spidle of Iowa State University and by Dan Grayson.
  1635. X
  1636. X     Some of the formatting of this documentation follows the example of
  1637. X     Sun Microsystems for their UNIX 4.2 Release.
  1638. X
  1639. XBUGS
  1640. X     The -n does not always correctly identify the targets which need to
  1641. X     be made.  It never misses required makes, but sometimes includes
  1642. X     unrequired makes.  It also incorrectly sets up the $?  macro in
  1643. X     these circumstances.  This does not happen during full execution.
  1644. X
  1645. X     MAKE allows spaces as well as TABs to introduce shell command
  1646. X     lines.
  1647. X
  1648. X     Target lines cannot use the double colon (::) syntax.
  1649. X
  1650. X     Once a dependency is made, MAKE assumes that the dependency file is
  1651. X     present for the remainder of the run.  If a rule subsequently
  1652. X     removes that file and future targets depend on it's existence,
  1653. X     unexpected errors may result.
  1654. X
  1655. X     Sometimes MAKE gets confused when searching for implicit rules, and
  1656. X     uses several rules instead of a single rule.  For example, the two
  1657. X     rules .c.o and .l.c may be used, rather than the more direct .l.o
  1658. X     rule.
  1659. X
  1660. X     If a number of command line flags are run together, and contains
  1661. X     either `f' or `d', the whole set of flags is dropped from
  1662. X     MAKEFLAGS.
  1663. X
  1664. X     The following flags are NOT supported:
  1665. X
  1666. X     -p  Print out the compete set of macro definitions and target
  1667. X         descriptions.
  1668. X
  1669. X     -P  Report dependencies recursively to show the entire dependency
  1670. X         hierarchy, without rebuilding any targets.
  1671. X
  1672. X     The following special targets are NOT supported:
  1673. X
  1674. X     .KEEP_STATE:
  1675. X     .MAKE_VERSION:
  1676. X     .PRECIOUS:
  1677. X     .SCCS_GET:
  1678. END_OF_FILE
  1679. if test 19978 -ne `wc -c <'make.doc'`; then
  1680.     echo shar: \"'make.doc'\" unpacked with wrong size!
  1681. fi
  1682. # end of 'make.doc'
  1683. fi
  1684. echo shar: End of archive 1 \(of 2\).
  1685. cp /dev/null ark1isdone
  1686. MISSING=""
  1687. for I in 1 2 ; do
  1688.     if test ! -f ark${I}isdone ; then
  1689.     MISSING="${MISSING} ${I}"
  1690.     fi
  1691. done
  1692. if test "${MISSING}" = "" ; then
  1693.     echo You have unpacked both archives.
  1694.     rm -f ark[1-9]isdone
  1695. else
  1696.     echo You still need to unpack the following archives:
  1697.     echo "        " ${MISSING}
  1698. fi
  1699. ##  End of shell archive.
  1700. exit 0
  1701.  
  1702.